package com.yswy.backstage.authfilter;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yswy.backstage.config.ApiNotAuthContext;
import com.yswy.domain.entity.user.User;
import com.yswy.backstage.service.SsoService;
import com.yswy.common.bean.auth.IgnoredUrlsProperties;
import com.yswy.common.enums.ResultStatus;
import com.yswy.common.model.ResultModel;
import com.yswy.domain.framework.context.CurrentUserContext;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;

import javax.annotation.Resource;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Map;
import java.util.Set;

@Order(1)
@WebFilter(filterName = "AuthFilter", urlPatterns = "/*")
public class AuthFilter implements Filter {
    private final Logger log = LoggerFactory.getLogger(this.getClass());

    public static final String ROOT = "4e92a3c21aa46fe075f0965d939090b9";

    private static final String CONNECTOR = "/";

    /**
     * 忽略验权配置
     */
    @Resource
    private IgnoredUrlsProperties ignoredUrlsProperties;

    @Resource
    private SsoService ssoService;

    @Override
    public void init(FilterConfig config) throws ServletException {
        log.info("授权过滤器初始化!");
        log.info("不需要认证的 URI：");
        for (String url : ignoredUrlsProperties.getUrls()) {
            log.info(url);
        }

    }

    @Override
    public void destroy() {
        log.info("授权过滤器注销!");
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        ObjectMapper mapper = new ObjectMapper();
        HttpServletRequest req = (HttpServletRequest) request;
        HttpServletResponse res = (HttpServletResponse) response;
        String reqAddress = request.getRemoteAddr();
        log.info(reqAddress + " 安全过滤器：" + req.getRequestURI() + " METHOD:" + req.getMethod());
        String requestURI = req.getRequestURI();
        //跨域设置
        cros(res);
        if (isAuth(requestURI)) {
            chain.doFilter(req, res);
            return;
        }


        res.setCharacterEncoding("UTF-8");
        res.setContentType("application/json; charset=utf-8");
        res.setStatus(HttpServletResponse.SC_OK);
        String[] strs = requestURI.split("/");
        String token = "";
        User user = null;

        if (strs.length >= 2) {
            token = req.getHeader("Authorization");
            log.info(reqAddress + " Authorization : " + token);
            //更新用户的TOKEN 过期时间，这样用户只要一直有操作，就永远不需要登录。
            user = ssoService.getUserByAuthToken(token);
            req.getSession().setAttribute("user", user);
        }

        if (StringUtils.isNotBlank(token)) {
            if (user != null) {
                CurrentUserContext.put(user);
            }

            //如果是管理员登录直接跳过验证
            if (ROOT.equals(token)) {
                chain.doFilter(req, res);
                return;
            }
            if (user != null) {
                //哪个模块下的哪个请求 e.g. /admin/login
                Set<Integer> userPermissionSet = ssoService.getPermissionMapByUser(user);
                Map<String, Long> userPermissionMap = ssoService.getAllModelPermission();
                Long requirePermissionId = userPermissionMap.get(requestURI);
                if (null != requirePermissionId && CollectionUtils.isNotEmpty(userPermissionSet) && userPermissionSet.contains(Math.toIntExact(requirePermissionId))) {

                    chain.doFilter(req, res);
                    return;
                } else {
                    log.info("current user: {}, do not have right permission！", user.getId());
                    log.info("current user permission：{}", userPermissionSet);
                    log.info("need permission：{}", requirePermissionId);
                }
            }
        }
        if (user == null) {
            res.getWriter().write(mapper.writeValueAsString(ResultModel.error(ResultStatus.LOGIN_OVER)));
        } else {
            res.getWriter().write(mapper.writeValueAsString(ResultModel.error("用户没有正确权限")));
        }
    }



    private boolean isAuth(String requestUrl) {
        long count = ignoredUrlsProperties.getUrls().stream().filter(s -> matchUrls(s , requestUrl)).count();
        long count1 = ApiNotAuthContext.urls.stream().filter(s -> matchUrls(s , requestUrl)).count();
        if(count >0
                ||   count1 >0
                || requestUrl.contains("swagger")
                || requestUrl.contains("api")
                || requestUrl.contains("druid")){
            return true;
        }
        return false;
    }


    private static boolean matchUrls(String pattern, String url) {
        // 将 pattern 转换为正则表达式
        String regex = pattern.replace("**", ".*");
        // 使用正则表达式进行匹配
        return url.matches(regex);
    }

    private HttpServletResponse cros(HttpServletResponse res) {

//        res.setHeader("Access-Control-Allow-Credentials", "true");
        res.setHeader("Access-Control-Allow-Origin", "*");
        res.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        res.setHeader("Access-Control-Max-Age", "3600");
//        res.setHeader("Access-Control-Allow-Headers", "*");
//        res.setHeader("Authorization", "Authorization");
        res.setHeader("Access-Control-Allow-Headers", "authorization,Authorization,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,*");
        res.setStatus(HttpServletResponse.SC_OK);
        return res;
    }

}
